﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
using ifunction.JPush.Web.Properties;
using ifunction.JPush;
using System.Text;
using ifunction;
using System.Security.Cryptography;

namespace ifunction.JPush.Web
{
    /// <summary>
    /// Summary description for JPush
    /// </summary>
    public class JPush : JPushWebHttpHandler<LocalJPushService>
    {
        const string SecretKey = "31A54963-34F9-41C4-A164-09C05C86DF27";

        /// <summary>
        /// Authenticates the specified request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="methodName">Name of the method.</param>
        /// <param name="postJson">The post json.</param>
        /// <param name="urlParameters">The URL parameters.</param>
        /// <param name="verificationCode">The verification code.</param>
        /// <returns><c>true</c> if pass authentication, <c>false</c> otherwise.</returns>
        public override bool Authenticate(HttpRequest request, string methodName, string postJson, NameValueCollection urlParameters, string verificationCode)
        {
            return ToMD5(string.Format("{0}{1}", postJson, SecretKey),Encoding.UTF8).Equals(verificationCode, StringComparison.InvariantCultureIgnoreCase);
        }

        #region MD5

        /// <summary>
        /// To md5.
        /// </summary>
        /// <param name="stringObject">The string object.</param>
        /// <param name="encoding">The encoding.</param>
        /// <returns>System.String.</returns>
        /// <exception cref="System.InvalidOperationException">ToMD5</exception>
        protected static string ToMD5(string stringObject, Encoding encoding = null)
        {
            if (encoding == null)
            {
                encoding = Encoding.UTF8;
            }

            try
            {
                byte[] data = encoding.GetBytes(stringObject);
                return ToMD5(data).ToUpperInvariant();
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("ToMD5", ex);
            }
        }

        /// <summary>
        /// To md5.
        /// </summary>
        /// <param name="bytes">The bytes.</param>
        /// <returns>System.String.</returns>
        /// <exception cref="System.InvalidOperationException">ToMD5</exception>
        protected static string ToMD5(byte[] bytes)
        {
            try
            {
                MD5CryptoServiceProvider md5Provider = new MD5CryptoServiceProvider();
                byte[] hash_byte = md5Provider.ComputeHash(bytes);
                string result = System.BitConverter.ToString(hash_byte);
                return result.Replace("-", "").ToUpperInvariant();
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("ToMD5", ex);
            }
        }

        #endregion
    }

    /// <summary>
    /// Class LocalJPushService.
    /// </summary>
    public class LocalJPushService : JPushService
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="LocalJPushService"/> class.
        /// </summary>
        public LocalJPushService()
            : base(Settings.Default.JPushAppKey, Settings.Default.JPushMasterSecret, Settings.Default.SqlConnection)
        {
        }

        /// <summary>
        /// Reports the exception.
        /// </summary>
        /// <param name="exception">The exception.</param>
        public override void ReportException(Exception exception)
        {
            throw exception;
        }
    }
}